/**
 * 
 */
package pl.kaczanowscy.tomek.ipdl;

import pl.kaczanowscy.tomek.ipdl.enums.Move;

/**
 * A simple {@link Game} between two players.
 * 
 * @author Tomek Kaczanowski
 * 
 */
public class TwoPlayersGame implements Game {

	private final int nbOfRounds;
	private final Strategy strategyA, strategyB;
	private final GameMatrix gameMatrix;
	private boolean played;

	/**
	 * Creates a two players game.
	 * 
	 * @param strategyA
	 *            first player
	 * @param strategyB
	 *            second player
	 * @param gameSettings
	 *            settings
	 */
	public TwoPlayersGame(Strategy strategyA, Strategy strategyB,
			GameSettings gameSettings) {
		this.strategyA = strategyA;
		this.strategyB = strategyB;
		this.nbOfRounds = gameSettings.getNbOfRounds();
		this.gameMatrix = gameSettings.getGameMatrix();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see pl.kaczanowscy.tomek.ipdl.Game#play()
	 */
	@Override
	public final GameResult play() {
		if (played) {
			throw new IllegalStateException("the game has already been played");
		}
		played = true;
		final GameResult gameResult = new GameResultImpl(strategyA, strategyB);
		for (int i = 0; i < nbOfRounds; i++) {
			RoundResult result = playRound(gameResult);
			strategyA.roundEnded(result);
			strategyB.roundEnded(result);
		}
		return gameResult;
	}

	private RoundResult playRound(GameResult gameResult) {
		Move moveA = strategyA.getMove();
		Move moveB = strategyB.getMove();
		int payoffA = gameMatrix.getPayoff(moveA, moveB);
		int payoffB = gameMatrix.getPayoff(moveB, moveA);
		gameResult.addPayoff(strategyA, payoffA);
		gameResult.addPayoff(strategyB, payoffB);
		return new RoundResultImpl(strategyA, payoffA, moveA, strategyB,
				payoffB, moveB);
	}
}
